"""
    Special search controller for autocomplete fields.
    Provides URL for search like this: `/Search/object_title?searchString=str`.
    All these methods retusn a list of pairs: (obj.title, obj.id).
"""

from datetime import date
from turbogears import controllers, expose
from mnemoply import model
from mnemoply.utils import isint

class SearchController(controllers.Controller):
    def search(self, model_object, condition, exposed_method, searchString, pre_condition=lambda obj: True):
        searchString = searchString.lower().strip()

        items = []

        if len(searchString) > 2:
            for obj in model_object.select():
                if pre_condition(obj) and (condition(obj).count(searchString) or str(obj.id) == searchString):
                    items.append((exposed_method(obj), obj.id))
            items.sort()
        return dict(textItems=items)

    @expose(format="json")
    def group(self, obj=None, searchString=None):
        return self.search(model.Group,
                           lambda obj: obj.title.lower(),
                           lambda obj: '%s (%d)' % (obj.title, obj.maxStudents - obj.cacheStudents),
                           searchString,
                           pre_condition=lambda obj: obj.endDate >= date.today() or obj.startDate == obj.endDate)

    @expose(format="json")
    def topic(self, obj=None, searchString=None):
        return self.search(model.Topic, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def plan_topic(self, obj=None, searchString=None):
        return self.search(model.PlanTopic, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def final_topic(self, obj=None, searchString=None):
        return self.search(model.FinalWorkTopic, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def student(self, obj=None, searchString=None):
        searchString = searchString.lower().strip()

        items = []

        if len(searchString) > 2:
            for obj in model.Student.select(model.Student.q.surname.contains(searchString)):
                items.append((obj.title, obj.id))
            items.sort()
        return dict(textItems=items)

    @expose(format="json")
    def student_in_group(self, obj=None, searchString=None):
        return self.search(model.StudentInGroup, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)
    
    @expose(format="json")
    def customer(self, obj=None, searchString=None):
        return self.search(model.Customer, lambda obj: obj.title.lower(),
            lambda obj: "%s (%d) %s" % (obj.title, obj.id, obj.phone[:10]), searchString)

    @expose(format="json")
    def person(self, obj=None, searchString=None):
        return self.search(model.Person, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def card(self, obj=None, searchString=None):
        return self.search(model.DiscontCard, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def agreement(self, obj=None, searchString=None):
        return self.search(model.StudentAgreement, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def temp_payment(self, obj=None, searchString=None):
        searchString = searchString.lower().strip()

        items = []

        if len(searchString) > 0 and isint(searchString):
            try:
                obj = model.TemporaryPaymentRecord.get(int(searchString))
                if obj.studentAgreement is None:
                    items.append((obj.title, obj.id))
            except:
                pass
        return dict(textItems=items)

    @expose(format="json")
    def coupon(self, obj=None, searchString=None):
        searchString = searchString.lower().strip()

        items = []

        if len(searchString) > 0 and isint(searchString):
            try:
                obj = model.Coupon.get(int(searchString))
                if not obj.temporaryPaymentRecord and not obj.isCancel:
                    items.append((obj.title, obj.id))
            except:
                pass
        return dict(textItems=items)

    @expose(format="json")
    def coupon_active(self, obj=None, searchString=None):
        return self.search(model.CouponActive, lambda obj: obj.title.lower(), lambda obj: obj.title, searchString)

    @expose(format="json")
    def project_defence(self, year=0, obj=None, searchString=None):
        if year:
            pre_condition=lambda obj: obj.group.initialPlan.year == int(year)
        else:
            pre_condition=lambda obj: True
        return self.search(
            model.ProjectDefence,
            lambda obj: obj.title.lower(),
            lambda obj: obj.title,
            searchString,
            pre_condition
        )

exposed = SearchController()
